package httpclient

import (
	"net/http"
	"time"
)

// Interceptor 定义请求/响应拦截器接口
type Interceptor interface {
	// Before 在请求发送前调用
	Before(req *http.Request) error
	// After 在收到响应后调用
	After(resp *http.Response, err error) error
}

// Chain 拦截器链
type Chain struct {
	interceptors []Interceptor
}

// NewChain 创建新的拦截器链
func NewChain(interceptors ...Interceptor) *Chain {
	return &Chain{
		interceptors: interceptors,
	}
}

// Add 添加拦截器
func (c *Chain) Add(interceptor Interceptor) *Chain {
	c.interceptors = append(c.interceptors, interceptor)
	return c
}

// Execute 执行拦截器链
func (c *Chain) Execute(req *http.Request, next func(*http.Request) (*http.Response, error)) (*http.Response, error) {
	// 执行前置拦截器
	for _, interceptor := range c.interceptors {
		if err := interceptor.Before(req); err != nil {
			return nil, err
		}
	}

	// 执行请求
	resp, err := next(req)

	// 执行后置拦截器
	for i := len(c.interceptors) - 1; i >= 0; i-- {
		if err := c.interceptors[i].After(resp, err); err != nil {
			return resp, err
		}
	}

	return resp, err
}

// 一些常用的拦截器实现

// LoggingInterceptor 日志拦截器
type LoggingInterceptor struct {
	Logger func(format string, args ...interface{})
}

func (i *LoggingInterceptor) Before(req *http.Request) error {
	if i.Logger != nil {
		i.Logger("Request: %s %s", req.Method, req.URL)
	}
	return nil
}

func (i *LoggingInterceptor) After(resp *http.Response, err error) error {
	if i.Logger != nil {
		if err != nil {
			i.Logger("Response Error: %v", err)
		} else {
			i.Logger("Response: %s", resp.Status)
		}
	}
	return err
}

// RetryInterceptor 重试拦截器
type RetryInterceptor struct {
	MaxRetries int
	RetryDelay time.Duration
}

func (i *RetryInterceptor) Before(req *http.Request) error {
	return nil
}

func (i *RetryInterceptor) After(resp *http.Response, err error) error {
	if err != nil || (resp != nil && resp.StatusCode >= 500) {
		// 实现重试逻辑
	}
	return err
}

// AuthInterceptor 认证拦截器
type AuthInterceptor struct {
	Username string
	Password string
	Token    string
}

func (i *AuthInterceptor) Before(req *http.Request) error {
	if i.Token != "" {
		req.Header.Set("Authorization", "Bearer "+i.Token)
	} else if i.Username != "" && i.Password != "" {
		req.SetBasicAuth(i.Username, i.Password)
	}
	return nil
}

func (i *AuthInterceptor) After(resp *http.Response, err error) error {
	return err
}
